﻿using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public static class ProtoLoader
{
    //We need to make a reference to the GameDataSerializer that wil be handling all of the data
    private static DataSerialize m_serializer = new DataSerialize();

    //our first function will load an object from resources. This is useful for if you had an editor script that created data that would be stored for later usage in the game, and you had saved it with the .bytes extension
    public static T loadObjectFromResources<T>(string resourcePath)
    {
        TextAsset objectAsset = Resources.Load(resourcePath, typeof(TextAsset)) as TextAsset;
        if (objectAsset == null)
        {
            return default(T);
        }

        T deserializedObject = default(T);

        //basically we just load the bytes of the text asset into a memory stream, and the deserialize it from there
        using (MemoryStream m = new MemoryStream(objectAsset.bytes))
        {
            deserializedObject = (T)m_serializer.Deserialize(m, null, typeof(T));
        }

        return deserializedObject;
    }

    //our next function is used for loading an object from a path. Basically for when you are loading progress and other sorts of stuffs
    public static T loadObjectFromPath<T>(string path)
    {
        //if the file doesn't exist we just return null. Since we are using a templated function the best we can do is default(T)
        if (!File.Exists(path))
        {
            return default(T);
        }

        T deserializedObject = default(T);

        using (FileStream f = new FileStream(path, FileMode.Open))
        {
            deserializedObject = (T)m_serializer.Deserialize(f, null, typeof(T));
        }

        return deserializedObject;
    }

    //Our third function will save the object to a file path. This is basically for saving game options, progress, whatever you can think of that you would need saved
    public static void saveObjectToPath<T>(string objPath, string fileName, T serializedObject)
    {
        if (!Directory.Exists(objPath))
        {
            Directory.CreateDirectory(objPath);
        }

        //after checking if the directory is there we serialize the object into a filestream to save it.

        using (FileStream f = new FileStream(objPath + fileName, FileMode.OpenOrCreate))
        {
            m_serializer.Serialize(f, serializedObject);
        }
    }

    //This function is actually useful for sending objects over an RPC function. Unity allows you to send a byte[]  through an RPC even though its not documented, so here you can serialize object data, send it over the network and then deserialize the object on the other end.
    public static byte[] serializeProtoObject<T>(T obj)
    {
        using (MemoryStream m = new MemoryStream())
        {
            m_serializer.Serialize(m, obj);
            return m.ToArray();
        }
    }

    //this is the opposite of the previous function. It allows you to send in a byte[] and return the object that it originally was. Very useful for networking
    public static T deserializeProtoObject<T>(byte[] bytes)
    {
        using (MemoryStream m = new MemoryStream(bytes))
        {
            return (T)m_serializer.Deserialize(m, null, typeof(T));
        }
    }
}
